iT邦幫忙

2022 iThome 鐵人賽

DAY 27
0
AI & Data

Object Detection and Image Processing with Python系列 第 27

《第27天》鋼胚序號辨識:資料集前處理

  • 分享至 

  • xImage
  •  

中鋼資料集與標記CSV檔

  1. 提供train約12,067張圖檔

  1. CSV檔內容

  1. 序號中包含:0-9與A-Z(扣掉I、O),共34個字(類別)。

現況

  1. 觀察資料集與標記CSV檔,發現有下列問題。

    1.1 CSV檔中,提供的座標錯誤

    • top left x出現負值

    • top left y大於bottom right y

    1.2 圖片中鋼胚有2個以上的序號

  2. 撰寫程式執行圖片裁切,獲得新資料集,優勢如下。

    2.1 鋼胚序號占整張圖片比例小,只裁切序號位置做為資料集,可提高待辨識物件的占比。

    • 裁切前

    • 裁切後

    2.2 篩除有2個以上序號的圖片與CSV檔錯誤標記的圖片


圖片裁切獲得新資料集

  1. 資料夾格式

    1.1 datasets_ocr

    1.2 public_training_data

  2. 流程與Python函式

    2.1 圖檔操作

    def cv_imread(image_path):
        image = cv2.imdecode(np.fromfile(image_path, dtype=np.uint8), -1)
        image = cv2.cvtColor(image, cv2.COLOR_BGRA2BGR)
    
        return image
    
    def show_img(name, image):
        cv2.imshow(name, image)
        cv2.waitKey(0)
    
    def cv_save(image, result_path):
        cv2.imencode('.jpg', image)[1].tofile(result_path)   
    

    2.2 讀取CSV檔獲得裁切的座標與標籤

    def bbox(df_path, image_path):
        df = pd.read_csv(df_path)
        image_id = image_path.split('/')[-1][:-4]
        xmin = df[df['filename'] == image_id]['top left x']
        xmax = df[df['filename'] == image_id]['bottom right x']
        ymin = df[df['filename'] == image_id]['top left y']
        ymax = df[df['filename'] == image_id]['bottom right y']
        label = df[df['filename'] == image_id]['label']
    
        box = {'xmin': int(xmin) - 28, 'xmax': int(xmax) + 28,
               'ymin': int(ymin) - 40, 'ymax': int(ymax) + 40}
    
        return box, label.values[0]
    

    2.3 接收座標進行圖片裁切

    def cut_img(image, box):
        result = image[box['ymin']:box['ymax'], box['xmin']:box['xmax']]
    
        return result
    
  3. 完整程式碼

import numpy as np
import pandas as pd
import cv2
import os

def cv_imread(image_path):
    image = cv2.imdecode(np.fromfile(image_path, dtype=np.uint8), -1)
    image = cv2.cvtColor(image, cv2.COLOR_BGRA2BGR)

    return image

def show_img(name, image):
    cv2.imshow(name, image)
    cv2.waitKey(0)

def cv_save(image, result_path):
    cv2.imencode('.jpg', image)[1].tofile(result_path)

def bbox(df_path, image_path):
    df = pd.read_csv(df_path)
    image_id = image_path.split('/')[-1][:-4]
    xmin = df[df['filename'] == image_id]['top left x']
    xmax = df[df['filename'] == image_id]['bottom right x']
    ymin = df[df['filename'] == image_id]['top left y']
    ymax = df[df['filename'] == image_id]['bottom right y']
    label = df[df['filename'] == image_id]['label']

    box = {'xmin': int(xmin) - 28, 'xmax': int(xmax) + 28,
           'ymin': int(ymin) - 40, 'ymax': int(ymax) + 40}

    return box, label.values[0]

def cut_img(image, box):
    result = image[box['ymin']:box['ymax'], box['xmin']:box['xmax']]

    return result

if __name__ == '__main__':
    df_path = './public_training_data.csv'

    source_path = './public_training_data/'
    images = os.listdir('./public_training_data/')
    image_path = [source_path+i for i in images]

    go_path = './data_go/'
    ng_path = './data_ng/'
    if not os.path.exists(go_path):
        os.makedirs(go_path)
    if not os.path.exists(ng_path):
        os.makedirs(ng_path)

    n = 1
    for i in image_path:
        print('※ 讀取第 {} 張圖'.format(n))
        box, label = bbox(df_path, i)
        label = label + '.jpg'
        image = cv_imread(i)
        # show_img('image', image)
        
        # 用來篩除異常圖片或異常標記
        try:
            result = cut_img(image, box)
            # show_img('result', result)
            result_path = go_path + label
            cv_save(result, result_path)
            print('{} 通過篩選'.format(result_path.split('/')[-1]))
            print('='*40)
        except:
            result_path = ng_path + label
            cv_save(image, result_path)
            print('{} 未通過篩選'.format(result_path.split('/')[-1]))
            print('=' * 40)
        n += 1
    print('※ 程式執行完畢')
  1. 執行程式

    4.1 執行結果

    4.2 通過篩選與裁切的圖片(以鋼胚序號作為檔名)

    4.3 被篩除的圖片(以鋼胚序號作為檔名)


小結

  1. 經過資料前處理,我們獲得乾淨的資料集(共11,569張)。使用LabelImg標記後,用於訓練YOLO模型。
  2. 下一站,我們將「標註獲得的PascalVOC xml」轉換成「YOLO txt」,執行YOLOv4與Scaled YOLOv4模型訓練。

讓我們繼續看下去...


參考資料

  1. 中鋼人工智慧挑戰賽-字元辨識

上一篇
《第26天》YOLO訓練流程與資料集COCO json格式
下一篇
《第28天》鋼胚序號辨識:YOLOv4與Scaled YOLOv4
系列文
Object Detection and Image Processing with Python30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
tom_hung
iT邦新手 5 級 ‧ 2023-07-13 16:23:42

有機會全部整理成一篇文章嗎?

你好,近期工作忙碌,現在才看到留言。目前暫時沒有計畫重新編撰文章。需要詳細、連貫的說明,歡迎私訊我。謝謝。

我要留言

立即登入留言